from functools import wraps
from typing import Callable, List, Dict, Any
from fastapi import Depends
from .auth import get_current_user
from .response import CommonErrors

def require_role(allowed_roles: List[int]):
    """
    权限检查装饰器
    
    Args:
        allowed_roles: 允许的角色列表 [1=学生, 2=教师, 3=管理员]
    """
    def decorator(func: Callable):
        @wraps(func)
        async def wrapper(*args, **kwargs):
            # 从kwargs中获取current_user，如果没有则通过Depends获取
            current_user = kwargs.get('current_user') or kwargs.get('user')
            
            if not current_user:
                # 如果装饰的函数没有用户参数，需要手动获取
                CommonErrors.unauthorized("需要登录")
            
            if current_user["role"] not in allowed_roles:
                role_names = {1: "学生", 2: "教师", 3: "管理员"}
                allowed_role_names = [role_names.get(role, f"角色{role}") for role in allowed_roles]
                CommonErrors.permission_denied(f"仅允许{'/'.join(allowed_role_names)}访问")
            
            return await func(*args, **kwargs)
        return wrapper
    return decorator

def require_student():
    """要求学生权限的装饰器"""
    return require_role([1])

def require_teacher():
    """要求教师权限的装饰器"""
    return require_role([2])

def require_admin():
    """要求管理员权限的装饰器"""
    return require_role([3])

def require_teacher_or_admin():
    """要求教师或管理员权限的装饰器"""
    return require_role([2, 3])

# 用于FastAPI路由的权限检查函数
async def get_current_student(current_user: Dict[str, Any] = Depends(get_current_user)) -> Dict[str, Any]:
    """获取当前学生用户"""
    if current_user["role"] != 1:
        CommonErrors.permission_denied("仅学生可访问")
    return current_user

async def get_current_teacher(current_user: Dict[str, Any] = Depends(get_current_user)) -> Dict[str, Any]:
    """获取当前教师用户"""
    if current_user["role"] != 2:
        CommonErrors.permission_denied("仅教师可访问")
    return current_user

async def get_current_admin(current_user: Dict[str, Any] = Depends(get_current_user)) -> Dict[str, Any]:
    """获取当前管理员用户"""
    if current_user["role"] != 3:
        CommonErrors.permission_denied("仅管理员可访问")
    return current_user

async def get_current_teacher_or_admin(current_user: Dict[str, Any] = Depends(get_current_user)) -> Dict[str, Any]:
    """获取当前教师或管理员用户"""
    if current_user["role"] not in [2, 3]:
        CommonErrors.permission_denied("仅教师或管理员可访问")
    return current_user 